package org.devgframwork.rabbitmq.connection;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

import java.util.concurrent.ExecutorService;

public abstract class AbstractConnectionFactory implements DevgConnectionFactory {

    private final Logger logger = LoggerFactory.getLogger(AbstractConnectionFactory.class);

    private final ConnectionFactory rabbitConnectionFactory;

    private volatile ExecutorService connectionExecutor;

    public AbstractConnectionFactory(ConnectionFactory rabbitConnectionFactory) {
        Assert.notNull(rabbitConnectionFactory, "Target ConnectionFactory must not be null");
        this.rabbitConnectionFactory = rabbitConnectionFactory;
        this.createConnection();
    }

    public enum ConnectionFactoryType {
        DEFAULT("default");

        private final String type;

        ConnectionFactoryType(String type) {
            this.type = type;
        }

        public String getType() {
            return this.type;
        }
    }

    public enum ChannelType {
        DEFAULT("default"),
        TRANSACTIONAL("transactional");
        private final String type;

        ChannelType(String type) {
            this.type = type;
        }

        public String getType() {
            return this.type;
        }
    }

    public ConnectionFactory getRabbitConnectionFactory() {
        return this.rabbitConnectionFactory;
    }

    public void setConnectionExecutor(ExecutorService connectionExecutor) {
        this.connectionExecutor = connectionExecutor;
    }

    public abstract int getChannelSize();

    public abstract Connection createConnection();

    public abstract Channel createChannel(ChannelType channelType);

    public abstract void closeChannelAndConnection(@Nullable Channel channel, ChannelType channelType);

}
